angular.module('app').directive('uiTable', function($templateCache, commonService, $timeout, $filter, $compile) {
  return {
    restrict: 'A',
    template: $templateCache.get('tpl/table.html'),
    scope: true,
    link: function(scope, element, attr) {
      var pageConfig = scope[attr.uiTable];
      scope.config = pageConfig;
      scope.attrName = attr.uiTable;
      scope.columnSize = scope.config.columnDefs.length + 1;
      scope.config.selectStyle = angular.isDefined(scope.config.selectStyle) ? scope.config.selectStyle : "radio";
      scope.config.pagination = angular.isDefined(scope.config.pagination) ? scope.config.pagination : false;
      scope.selectItems = {};
      scope.selectNum = 0;
      init();
      refresh();
      scope.countSelectedNum = function() {
        scope.selectNum = angular.keys(scope.selectItems).length;
        scope.$apply();
      }
      scope.config.getSelectItems = function() {
        return angular.values(scope.selectItems);
      }
      scope.config.clearSelectItems = function(keys) {
        if(keys == null||keys.length <= 0){
          keys = angular.keys(scope.selectItems);
        }
        angular.forEach(keys, function(key){
          delete scope.selectItems[key];
        });
        scope.selectNum = angular.keys(scope.selectItems).length;
      }
      function refresh(isQuery) {
        if(scope.searchCriteria==undefined){
          scope.searchCriteria ={};
        }
        var searchCriteria = scope.searchCriteria;
        searchCriteria.limit = scope.limit;
        scope.currentPage = angular.isDefined(scope.currentPage) ? scope.currentPage : 1;
        if(isQuery){
          scope.currentPage = 1;
        }
        searchCriteria.page = scope.currentPage;
        var needSorted = !angular.isEmpty(scope.config.defaultSortOptions);
        if (needSorted) {
          if(angular.isEmpty(scope.orderByClause)){
            scope.orderByClause =  scope.config.defaultSortOptions.field;
            scope.orderBy = scope.config.defaultSortOptions.direction;
          }
          searchCriteria.orderByClause = scope.orderByClause;
          searchCriteria.orderBy = scope.orderBy;
        }
        commonService.post(pageConfig.url, searchCriteria).then(function(response) {
          if (angular.isEmpty(pageConfig.data)) {
            scope.entrys = response.data;
          } else {
            scope.entrys = response.data[pageConfig.data];
          }
          scope.count = response.data.count;
          if (scope.config.pagination) {
            refreshPagination();
          }
          refreshColumn();
        });
      }
      scope.config.refresh = refresh;
      // 刷新表格
      function refreshColumn() {
        $timeout(function() {
          var trs = element.find("tr");
          var pagination = scope.config.pagination;
          var size = pagination || scope.config.selectStyle == 'checkbox' ? trs.length - 1 : trs.length;
          if (!angular.isEmpty(trs)) {
            for (var i = 1; i < size; i++) {
              $(trs[i]).css({
                "cursor": "pointer"
              });
              // 绑定点击选中效果
              $(trs[i]).bind('click', function() {
                var id = null;
                if (scope.config.selectStyle == 'radio') {
                  var radio = $(this).find(":radio").first();
                  radio.prop("checked", true);
                  id = radio.attr("id");
                } else {
                  var checkbox = $(this).find(":checkbox").first();
                  id = checkbox.attr("id");
                  var row = scope.entrys[id];
                  if (checkbox.prop("checked")) {
                    checkbox.prop("checked", false);
                    delete scope.selectItems[row[scope.config.dataKey]];
                  } else {
                    checkbox.prop("checked", true);
                    scope.selectItems[row[scope.config.dataKey]] = row;
                  }
                  scope.countSelectedNum();
                }
                if (scope.config.afterSelectionChange) {
                  scope.config.afterSelectionChange(scope.entrys[id]);
                }
              });
              if (!angular.isEmpty(scope.selectItems[scope.entrys[i - 1][scope.config.dataKey]])) {
                $(trs[i]).find(":checkbox").prop("checked", true);
              }
              $(trs[i]).find("td").each(function(j) {
                if (j != 0) {
                  // 添加超出省略号效果
                  var ellipsis = scope.config.columnDefs[j - 1].ellipsis;
                  var field = scope.config.columnDefs[j - 1].field;
                  var data = scope.entrys[i - 1][field];
                  var cellFilter = scope.config.columnDefs[j - 1].cellFilter;
                  if (cellFilter != null) {
                    if (cellFilter.dataStatus != null) {
                      data = scope.$msg(cellFilter.dataStatus)[data];
                    } else if (cellFilter.date == 'dateTime') {
                      data = $filter('date')(data, 'yyyy-MM-dd HH:mm:ss');
                    } else if (cellFilter.date == 'date') {
                      data = $filter('date')(data, 'yyyy-MM-dd');
                    }
                  }
                  if (!angular.isEmpty(ellipsis) && ellipsis) {
                    $(this).attr("title", data);
                    $(this).css({
                      "overflow": "hidden",
                      "white-space": "nowrap",
                      "text-overflow": "ellipsis"
                    });
                  }
                  // 添加模板效果
                  var template = scope.config.columnDefs[j - 1].template;
                  if (!angular.isEmpty(template) && template) {
                    var child = scope.$new();
                    child.row = scope.entrys[i - 1];
                    child.index = i;
                    data = $compile(template)(child);
                  }
                  $(this).append(data);
                }
              });
            }
          }
        });
      }
      // 刷新page
      function refreshPagination() {
        $timeout(function() {
          scope.calcTotalPages();
          scope.pages = scope.getPages(scope.currentPage, scope.totalPages, scope.maxSize);
        });
      }
      // 初始化管理
      function init() {
        $timeout(function() {
          var needSorted = !angular.isEmpty(scope.config.defaultSortOptions);
          // checkbox全选框
          if ("checkbox" == scope.config.selectStyle) {
            element.find(":checkbox").first().bind('click', function() {
              var checked = $(this).prop("checked");
              element.find($("tr :checkbox:gt(0)")).prop("checked", checked);
              if (angular.isEmpty(scope.config.dataKey)) { return; }
              $.each(scope.entrys, function(i) {
                var row = scope.entrys[i];
                if (checked) {
                  scope.selectItems[row[scope.config.dataKey]] = row;
                } else {
                  delete scope.selectItems[row[scope.config.dataKey]];
                }
                scope.countSelectedNum();
              })
            });
          }
          element.find("th").each(function(i) {
            if (i != 0) {
              // 添加宽度样式
              if (!angular.isEmpty(scope.config.columnDefs[i - 1].width)) {
                $(this).css("width", scope.config.columnDefs[i - 1].width);
              }
              if (needSorted) {
                var field = scope.config.defaultSortOptions.field;
                var direction = scope.config.defaultSortOptions.direction;
                scope.orderByClause = field;
                scope.orderBy = direction;
                // 添加排序样式
                if (field == scope.config.columnDefs[i - 1].field) {
                  if (scope.config.defaultSortOptions.direction == 'desc') {
                    $(this).append("<i class=\"fa fa-angle-down\"></i>")
                  } else {
                    $(this).append("<i class=\"fa fa-angle-up\"></i>")
                  }
                } else {
                  $(this).append("<i class=\"fa\"></i>")
                }
                // 添加鼠标手效果
                $(this).css({
                  "cursor": "pointer"
                });
                // 绑定点击排序效果
                $(this).bind('click', function() {
                  var iEle = $(this).find("i");
                  var cls = iEle.attr("class");
                  var id = $(this).attr("id");
                  $(this).parent().find("i").removeClass("fa-angle-down").removeClass("fa-angle-up");
                  if ("fa fa-angle-down" == cls) {
                    iEle.removeClass("fa-angle-down").addClass("fa-angle-up");
                    scope.orderBy = "asc";
                  } else {
                    iEle.removeClass("fa-angle-up").addClass("fa-angle-down");
                    scope.orderBy = "desc";
                  }
                  scope.orderByClause = scope.config.columnDefs[id].field;
                  scope.currentPage = 1;
                  refresh();
                });
              }
            }
          })
          // 分页处理
          scope.maxSize = angular.isDefined(scope.config.maxSize) ? scope.config.maxSize : 10;
          scope.limit = angular.isDefined(scope.config.limit) ? scope.config.limit : 10;
          scope.currentPage = angular.isDefined(scope.currentPage) ? scope.currentPage : 1;
          // 计算总页数
          scope.calcTotalPages = function() {
            scope.totalPages = scope.limit < 1 ? 1 : Math.ceil(scope.count / scope.limit);
            scope.totalPages = Math.max(scope.totalPages || 0, 1);
          }
          // 提供页数选择方法
          scope.selectPage = function(currentPage) {
            if (scope.currentPage !== currentPage && currentPage > 0 && currentPage <= scope.totalPages) {
              scope.currentPage = currentPage;
              refresh();
            }
          };
          // 提供是否第一页
          scope.noPrevious = function() {
            return scope.currentPage === 1;
          };
          // 提供是否最后一页
          scope.noNext = function() {
            return scope.currentPage === scope.totalPages;
          };
          function makePage(number, text, isActive) {
            return {
              number: number,
              text: text,
              active: isActive
            };
          }
          // 提供页码工厂
          scope.getPages = function getPages(currentPage, totalPages, maxSize) {
            var pages = [];
            var startPage = 1, endPage = totalPages;
            var rotate = true;
            var isMaxSized = (angular.isDefined(maxSize) && maxSize < totalPages);
            if (isMaxSized) {
              if (rotate) {
                startPage = Math.max(currentPage - Math.floor(maxSize / 2), 1);
                endPage = startPage + maxSize - 1;
                if (endPage > totalPages) {
                  endPage = totalPages;
                  startPage = endPage - maxSize + 1;
                }
              } else {
                startPage = ((Math.ceil(currentPage / maxSize) - 1) * maxSize) + 1;
                endPage = Math.min(startPage + maxSize - 1, totalPages);
              }
            }
            for (var number = startPage; number <= endPage; number++) {
              var page = makePage(number, number, number === currentPage);
              pages.push(page);
            }
            if (isMaxSized && !rotate) {
              if (startPage > 1) {
                var previousPageSet = makePage(startPage - 1, '...', false);
                pages.unshift(previousPageSet);
              }
              if (endPage < totalPages) {
                var nextPageSet = makePage(endPage + 1, '...', false);
                pages.push(nextPageSet);
              }
            }
            return pages;
          }
        })
      }
    }
  };
});

angular.module("app").run(["$templateRequest", function($templateRequest) {
  $templateRequest("tpl/table.html");
}]);
